package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.config.BaseContext;
import com.itheima.dao.OrdersDao;
import com.itheima.global.BusinessException;
import com.itheima.po.*;
import com.itheima.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author Andy
 * @Description //TODO OrdersService
 * @Date 2022/3/19 2:44 下午
 * @Version 1.0
 **/
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersDao, Orders>
        implements OrdersService {


//    目前该方法已知的
//     body :{"remark":"","payMethod":1,"addressBookId":"1505004591069016065"}
//     BaseContext.getCurrentId()
//
//     表中需要存储的数据
//    订单与订单流水（订单详情）保存都需要哪些数据?
//   订单表
//  id                 雪花算法生成
//  number             复用ID的值 ID与number是相同的
//  status             数据库表中 DEFAULT '1' 数据库来默认填充
//  user_id            当前操作用户 BaseContext.getCurrentId()
//  address_book_id    public void submit(Orders orders)  前端传过来的数据
//  order_time         当前时间
//  checkout_time      当前时间
//  pay_method         public void submit(Orders orders)  前端传过来的数据
//  amount             实收金额，购物车中的菜品或套餐经过份数与单价计算累计合得来
//  remark             public void submit(Orders orders)  前端传过来的数据
//  phone              用户默认地址中的手机号 通过address_book_id获得地址数据进而拿到手机号数据
//  address            用户默认地址中的地址详情 通过address_book_id获得地址数据进而拿到地址详情数据
//  user_name          通过BaseContext.getCurrentId()从数据拿到用户的数据，获得用户名字
//  consignee          用户默认地址中的收件人 通过address_book_id获得地址数据进而拿到收件人数据
//
//  订单流水表
//  id                 雪花算法生成 与订单的ID是不同的
//  name               可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置name值
//  image              可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置image值
//  order_id           订单的ID
//  dish_id            可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置dish_id    值
//  setmeal_id         可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置setmeal_id 值
//  dish_flavor        可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置dish_flavor值
//  number             可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置number     值
//  amount             可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置amount     值
//

    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private UserService userService;
    @Autowired
    private OrderDetailService orderDetailService;

    @Override
    @Transactional(rollbackFor = {})
    public void submit(Orders orders) {

//        1 从数据中获取当前用户下单地址，如果下单地址不存在，则抛出异常
//        2 从数据中获取当前用户购物车数据，如果购物车为空，则抛出异常
//        3 根据当前用户登录ID，从数据中拿到用户数据
//        4 构建订单，并保存到数据库中
//        5 构建订单流水数据，并保存到数据库中
//        6 清空购物车

//        1 从数据中获取当前用户下单地址，如果下单地址不存在，则抛出异常
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        if (null == addressBook) {
            throw new BusinessException("当用户下单时，必须填写地址");
        }

//        2 从数据中获取当前用户购物车数据，如果购物车为空，则抛出异常
        LambdaQueryWrapper<ShoppingCart> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(lambdaQueryWrapper);
        if (null == shoppingCartList || shoppingCartList.size() == 0) {
            throw new BusinessException("当用户下单时，必须选择了菜品或套餐");
        }

//        3 根据当前用户登录ID，从数据中拿到用户数据
        User user = userService.getById(BaseContext.getCurrentId());

//        4 构建订单，并保存到数据库中
        //  id                 雪花算法生成
//  number             复用ID的值 ID与number是相同的
//  status             数据库表中 DEFAULT '1' 数据库来默认填充
//  user_id            当前操作用户 BaseContext.getCurrentId()
//  address_book_id    public void submit(Orders orders)  前端传过来的数据
//  order_time         当前时间
//  checkout_time      当前时间
//  pay_method         public void submit(Orders orders)  前端传过来的数据
//  amount             实收金额，购物车中的菜品或套餐经过份数与单价计算累计合得来
//  remark             public void submit(Orders orders)  前端传过来的数据
//  phone              用户默认地址中的手机号 通过address_book_id获得地址数据进而拿到手机号数据
//  address            用户默认地址中的地址详情 通过address_book_id获得地址数据进而拿到地址详情数据
//  user_name          通过BaseContext.getCurrentId()从数据拿到用户的数据，获得用户名字
//  consignee          用户默认地址中的收件人 通过address_book_id获得地址数据进而拿到收件人数据

        orders.setId(IdWorker.getId());
        orders.setNumber(orders.getId() + "");
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());

        BigDecimal amount = new BigDecimal(0);
        for (int i = 0; i < shoppingCartList.size(); i++) {
            ShoppingCart dishOrSetmeal = shoppingCartList.get(i);
//            单价*份数
            BigDecimal multiply = dishOrSetmeal.getAmount().multiply(new BigDecimal(dishOrSetmeal.getNumber()));
//            累计求和
            amount = amount.add(multiply);
        }
        orders.setAmount(amount);

        orders.setPhone(addressBook.getPhone());
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName()) +
                                  (addressBook.getCityName() == null ? "" : addressBook.getCityName()) +
                                  (addressBook.getDistrictName() == null ? "" : addressBook
                                          .getDistrictName()) + addressBook.getDetail());
        orders.setUserName(user.getName());
        orders.setConsignee(addressBook.getConsignee());
        this.save(orders);

//        5 构建订单流水数据，并保存到数据库中
        //  订单流水表
//  id                 雪花算法生成 与订单的ID是不同的
//  name               可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置name值
//  image              可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置image值
//  order_id           订单的ID
//  dish_id            可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置dish_id    值
//  setmeal_id         可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置setmeal_id 值
//  dish_flavor        可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置dish_flavor值
//  number             可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置number     值
//  amount             可以通过BaseContext.getCurrentId()从数据拿到购物车数据，进而设置amount     值
//          定义订单流水集合收集数据用
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (int i = 0; i < shoppingCartList.size(); i++) {
            ShoppingCart dishOrSetmeal = shoppingCartList.get(i);
            OrderDetail orderDetail = new OrderDetail();
//            BeanUtils.copyProperties(dishOrSetmeal, orderDetail);
////            orderDetail.setOrderId(orders.getId());
            orderDetail.setName(dishOrSetmeal.getName());
            orderDetail.setImage(dishOrSetmeal.getImage());
            orderDetail.setOrderId(orders.getId());
            orderDetail.setDishId(dishOrSetmeal.getDishId());
            orderDetail.setSetmealId(dishOrSetmeal.getSetmealId());
            orderDetail.setDishFlavor(dishOrSetmeal.getDishFlavor());
            orderDetail.setNumber(dishOrSetmeal.getNumber());
            orderDetail.setAmount(dishOrSetmeal.getAmount());
            orderDetailList.add(orderDetail);
        }
        orderDetailService.saveBatch(orderDetailList);

//        6 清空购物车
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq( ShoppingCart::getUserId, BaseContext.getCurrentId());
//        2. service调用review方法
        shoppingCartService.remove(queryWrapper);

    }
}
